package com.wgchao.identityrightsmanagement;

import com.alibaba.fastjson.JSON;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * @ClassName: LogRecordAspect
 * @author: wgchao
 * @createTime: 2019/9/4 9:59 AM
 * @Description: 接口日志打印
 */
@Aspect
@Component
@Order(-11)
public class LogRecordAspect {
    private static final Logger logger = LoggerFactory.getLogger(LogRecordAspect.class);

    // 定义切点Pointcut
    @Pointcut("execution(* com.wgchao.identityrightsmanagement.application.controller..*.*(..))")
    public void excudeService() {
    }


    @Around("excudeService()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();

        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        String uri = request.getRequestURI();
        String queryString = request.getQueryString();

        Object[] args = pjp.getArgs();
        Object[] arguments  = new Object[args.length];
        for (int i = 0; i < args.length; i++) {
            if (args[i] instanceof ServletRequest || args[i] instanceof ServletResponse || args[i] instanceof MultipartFile) {
                //ServletRequest不能序列化，从入参里排除，否则报异常：java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
                //ServletResponse不能序列化 从入参里排除，否则报异常：java.lang.IllegalStateException: getOutputStream() has already been called for this response
                continue;
            }
            arguments[i] = args[i];
        }
   //     System.out.println(JSON.toJSONString(args));
        String params = "";
        //获取请求参数集合并进行遍历拼接
        if(args.length>0){
            if("POST".equals(method)){
                params = JSON.toJSONString(arguments[0]);
                ;
            }else if("GET".equals(method)){
                params = queryString;
            }else if("PUT".equals(method)){
                params = JSON.toJSONString(arguments[0]);
            }else if("DELETE".equals(method)){
                params = JSON.toJSONString(arguments[0]);
            }
        }


        logger.info("请求开始===:"+url+"["+method+"]  "+"["+params+"]");

        // result的值就是被拦截方法的返回值
        Object result = pjp.proceed();
   //     Gson gson = new Gson();
        logger.info("请求结束===:" +url+"["+method+"]  "+ JSON.toJSONString(result));
        return result;
    }

    public static Map<String, Object> getKeyAndValue(Object obj) {
//        Map<String, Object> map = new MyHashMap<>();
////        // 得到类对象
////        Class userCla = (Class) obj.getClass();
////        /* 得到类中的所有属性集合 */
////        Field[] fs = userCla.getDeclaredFields();
////        for (int i = 0; i < fs.length; i++) {
////            Field f = fs[i];
////            f.setAccessible(true); // 设置些属性是可以访问的
////            Object val = new Object();
////            try {
////                val = f.get(obj);
////                // 得到此属性的值
////                map.put(f.getName(), val);// 设置键值
////            } catch (IllegalArgumentException e) {
////                e.printStackTrace();
////            } catch (IllegalAccessException e) {
////                e.printStackTrace();
////            }
////
////        }
        return null;
    }
}
